home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / char / pty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  2.6 KB  |  109 lines

  1. /*
  2.  *  linux/kernel/chr_drv/pty.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. /*
  8.  *    pty.c
  9.  *
  10.  * This module exports the following pty function:
  11.  * 
  12.  *     int  pty_open(struct tty_struct * tty, struct file * filp);
  13.  */
  14.  
  15. #include <linux/errno.h>
  16. #include <linux/sched.h>
  17. #include <linux/tty.h>
  18. #include <linux/fcntl.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/string.h>
  21.  
  22. #include <asm/system.h>
  23. #include <asm/bitops.h>
  24.  
  25. #define MIN(a,b)    ((a) < (b) ? (a) : (b))
  26.  
  27. static void pty_close(struct tty_struct * tty, struct file * filp)
  28. {
  29.     if (!tty)
  30.         return;
  31.     if (IS_A_PTY_MASTER(tty->line)) {
  32.         if (tty->count > 1)
  33.             printk("master pty_close: count = %d!!\n", tty->count);
  34.     } else {
  35.         if (tty->count > 2)
  36.             return;
  37.     }
  38.     wake_up_interruptible(&tty->secondary.proc_list);
  39.     wake_up_interruptible(&tty->read_q.proc_list);
  40.     wake_up_interruptible(&tty->write_q.proc_list);
  41.     if (!tty->link)
  42.         return;
  43.     wake_up_interruptible(&tty->link->secondary.proc_list);
  44.     wake_up_interruptible(&tty->link->read_q.proc_list);
  45.     wake_up_interruptible(&tty->link->write_q.proc_list);
  46.     if (IS_A_PTY_MASTER(tty->line))
  47.         tty_hangup(tty->link);
  48.     else {
  49.         start_tty(tty);
  50.         set_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
  51.     }
  52. }
  53.  
  54. static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
  55. {
  56.     unsigned long count, n;
  57.     struct tty_queue *fq, *tq;
  58.  
  59.     if (from->stopped || EMPTY(&from->write_q))
  60.         return;
  61.     fq = &from->write_q;
  62.     tq = &to->read_q;
  63.     count = MIN(CHARS(fq), LEFT(tq));
  64.     while (count) {
  65.         n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
  66.             count);
  67.         memcpy(&tq->buf[tq->head], &fq->buf[fq->tail], n);
  68.         count -= n;
  69.         fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
  70.         tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
  71.     }
  72.     TTY_READ_FLUSH(to);
  73.     if (LEFT(fq) > WAKEUP_CHARS)
  74.         wake_up_interruptible(&fq->proc_list);
  75.     if (from->write_data_cnt) {
  76.         set_bit(from->line, &tty_check_write);
  77.         mark_bh(TTY_BH);
  78.     }
  79. }
  80.  
  81. /*
  82.  * This routine gets called when tty_write has put something into
  83.  * the write_queue. It copies the input to the output-queue of its
  84.  * slave.
  85.  */
  86. static void pty_write(struct tty_struct * tty)
  87. {
  88.     if (tty->link)
  89.         pty_copy(tty,tty->link);
  90. }
  91.  
  92. int pty_open(struct tty_struct *tty, struct file * filp)
  93. {
  94.     if (!tty || !tty->link)
  95.         return -ENODEV;
  96.     if (IS_A_PTY_SLAVE(tty->line))
  97.         clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
  98.     tty->write = tty->link->write = pty_write;
  99.     tty->close = tty->link->close = pty_close;
  100.     wake_up_interruptible(&tty->read_q.proc_list);
  101.     if (filp->f_flags & O_NDELAY)
  102.         return 0;
  103.     while (!tty->link->count && !(current->signal & ~current->blocked))
  104.         interruptible_sleep_on(&tty->link->read_q.proc_list);
  105.     if (!tty->link->count)
  106.         return -ERESTARTSYS;
  107.     return 0;
  108. }
  109.